/**
 * Copyright (c) 2017 ucsmy.com, All rights reserved.
 */
package itsm.isperp.module.controller.api.wechat.v2;

import itsm.isperp.framework.core.context.ContextHolder;
import itsm.isperp.framework.data.domain.DataResponse;
import itsm.isperp.framework.domain.UploadInfo;
import itsm.isperp.framework.service.UploadFileService;
import itsm.isperp.framework.utils.FileUploadUtils;
import itsm.isperp.framework.utils.HibernateUUIDGenerator;
import itsm.isperp.framework.web.request.JqGridFilterRuleOp;
import itsm.isperp.framework.web.request.JqGridRequest;
import itsm.isperp.module.entity.app.AppUploadFile;
import itsm.isperp.module.entity.app.AppUser;
import itsm.isperp.module.service.app.AppUploadFileService;
import itsm.isperp.module.service.app.AppUserService;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import sun.misc.BASE64Decoder;

/**
 * @Description:
 * @Author: legen
 * @Created Date: 2017-09-15-0015.
 * @LastModifyDate: 2017-09-15-0015.
 * @LastModifyBy: legen
 * @Version:
 */
public class BaseController {

    private static final Logger logger = LoggerFactory.getLogger(BaseController.class);

    protected final String INCIDENT_PROCESS = "incidentProcess";
    protected final String PROBLEM_PROCESS = "problemProcess";
    protected final String CHANGE_PROCESS = "changeProcess";
    protected final String RELEASE_PROCESS = "releaseProcess";
    protected final String TASK_PROCESS = "taskProcess";
    protected final String KNOWLEDGE_PROCESS = "knowledgeProcess";

    @Resource(name = "isperp.authenticationManager")
    private AuthenticationManager authenticationManager;

    @Resource(name = "appUserService")
    private AppUserService appUserService;
    
    @Autowired
    private AppUploadFileService appUploadFileService;


    protected void login(String username)
            throws Exception {
        AppUser u = (AppUser) appUserService.loadUserByUsername(username);
        if (u == null) {
            throw new Exception("用户不存在");
        }

        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(u.getUsername(), u.getPassword());

        token.setDetails(new WebAuthenticationDetails(ContextHolder.getRequest()));
        Authentication authenticatedUser = authenticationManager.authenticate(token);

        SecurityContextHolder.getContext().setAuthentication(authenticatedUser);

        CompositeSessionAuthenticationStrategy concurrentSessionControlStrategy = ContextHolder.getSpringBean("concurrentSessionControlStrategy");
    }

    @ExceptionHandler({Exception.class})
    public @ResponseBody
    Map<String, Object> exceptionHadler(Exception e) {
        logger.error(e.getMessage(), e);

        Map<String, Object> resutl = new HashMap<>();
        resutl.put("success", false);
        resutl.put("message", e.getMessage());
        return resutl;
    }

    protected void addNullColumns(JqGridRequest request, Map<String, Object> map) {
        for (String column : request.getSelectColumns()) {
            if (!map.containsKey(column)) {
                map.put(column, null);
            }
        }
    }

    protected void addNullColumns(JqGridRequest request, Iterable<Map<String, Object>> maps) {
        for (String column : request.getSelectColumns()) {
            for (Map<String, Object> map : maps) {
                if (!map.containsKey(column)) {
                    map.put(column, null);
                }
            }
        }
    }

    protected List<Map<String, Object>> filterColumns(Iterable<Map<String, Object>> maps, String... columns) {
        List<Map<String, Object>> result = new ArrayList<>();
        for (Map<String, Object> map : maps) {
            Map<String, Object> newMap = new HashMap<>();
            for (String column : columns) {
                if (map.containsKey(column)) {
                    newMap.put(column, map.get(column));
                } else {
                    newMap.put(column, null);
                }
            }
            result.add(newMap);
        }
        return result;
    }

    private UploadFileService<UploadInfo> uploadFileService;

    protected void saveImages(String sourceId, UploadImage[] images) {
        if (images == null) {
            return;
        }

        if (uploadFileService == null) {
            uploadFileService = ContextHolder.getSpringBean("appUploadFileService");
        }

        for (UploadImage image : images) {

            String[] imageStrings = image.getData().split(",");
            String contentType = imageStrings[0].replace("data:", "").replace("base64", "");
            String imageData = imageStrings[1];

            UploadInfo uploadInfo = new AppUploadFile();
            uploadInfo.setId(HibernateUUIDGenerator.generate());
            uploadInfo.setName(image.getName());
            uploadInfo.setExt(uploadInfo.getName().substring(uploadInfo.getName().lastIndexOf(".") + 1));
            uploadInfo.setContentType(contentType);
            uploadInfo.setSourceId(sourceId);

            String yyyyMM = DateFormatUtils.format(new Date(), "yyyyMM");
            try {


                BASE64Decoder decoder = new BASE64Decoder();
                // Base64解码
                byte[] b = decoder.decodeBuffer(imageData);
                for (int i = 0; i < b.length; ++i) {
                    if (b[i] < 0) {// 调整异常数据
                        b[i] += 256;
                    }
                }

                File file = FileUploadUtils.createFile(uploadInfo, yyyyMM);
                OutputStream out = new FileOutputStream(file);
                out.write(b);
                out.flush();
                out.close();

                String filePath = ContextHolder.getUploadFileStore() + yyyyMM + "/" + file.getName();
                uploadInfo.setPath(filePath);
                uploadInfo.setSize(file.length());
            } catch (Exception e) {
                e.printStackTrace();
            }

            // 记录文件删除在信息到数据库中
            uploadFileService.saveOrUpdate(uploadInfo);
        }
    }

    protected void uploadPositionInfo(String username, String longitude, String latitude) {

        if (StringUtils.isEmpty(longitude) || StringUtils.isEmpty(latitude)) {
            return;
        }

        AppUser user = appUserService.findByUsername(username);
        if (user == null) {
            return;
        }

        // 更新工程师的地理位置
        user.setLongitude(longitude);
        user.setLatitude(latitude);
        Set<String> includeColumns = new HashSet<>();
        includeColumns.add("longitude");
        includeColumns.add("latitude");
        appUserService.saveOrUpdateSpecific(user, includeColumns);
    }
    
    protected List<String> getImages(String sourceId) {
      JqGridRequest request = new JqGridRequest();
      request.setPageable(false);
      request.addFilterRule("source_id", JqGridFilterRuleOp.eq, sourceId);
      DataResponse<AppUploadFile> images = appUploadFileService.findAll(request);
      List<String> imagePaths = new ArrayList<>(images.size());
      for (AppUploadFile image : images) {
          imagePaths.add(image.getPath());
      }
      return imagePaths;
  }

}
